package com.powernode.controller;

import com.alibaba.fastjson.JSONObject;
import com.powernode.api.model.FinanceAccount;
import com.powernode.api.model.User;
import com.powernode.api.service.FinanceService;
import com.powernode.api.service.UserService;
import com.powernode.common.Code;
import com.powernode.constants.RedisKey;
import com.powernode.resp.Result;
import com.powernode.service.SmsService;
import com.powernode.util.CommonUtil;
import com.powernode.util.TokenUtil;
import com.powernode.vo.UserInfo;
import com.powernode.vo.UserParam;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
public class UserController {

    @DubboReference(interfaceClass = UserService.class,version = "1.0.0")
    private UserService userService;

    @Autowired
    private SmsService smsService;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference(interfaceClass =FinanceService.class,version = "1.0.0")
    private FinanceService financeService;

    /*能否注册  是否已注册*/
    @GetMapping("/v1/user/isRegister")
    public Result phoneExists(String phone){
        Result result = Result.FAILURE();
        result.setCodeEnum(Code.PHONE_FORMAT_ERROR);
        /*验证手机号码的格式*/
        if (CommonUtil.checkPhone(phone)){
            /*去数据库中  查询 手机号码*/
            User user = userService.queryUserByPhone(phone);
            /*判断user对象是否为null*/
            if (user==null){
                /*查无此用户  可以 注册*/
                result=Result.SUCCESS();
            }else {
                result.setCodeEnum(Code.PHONE_HAD_REGISTER);
            }
        }
        return  result;
    }


    /**
     * 注册  axios 默认发送 json数据
     * @param userParam  用户输入的数据 手机号码 密码 验证码 前端发送的json数据  需要转换
     * @return
     */
    @PostMapping("/v1/user/register")
    public Result userRegister(@RequestBody UserParam userParam){
        Result result =Result.FAILURE();
        /*1 检查数据  手机号码格式 密码长度（md5加密之后长度为 32）*/
        if (CommonUtil.checkPhone(userParam.getPhone())&&
            userParam.getCode()!=null&&userParam.getCode().length()==6
            &&userParam.getLoginPassword()!=null&&userParam.getLoginPassword().length()==32
        ){
            /*2检查验证码 是否 正确*/
            if (smsService.checkRegisterCode(userParam.getPhone(),userParam.getCode())){
                /*3 验证手机号码是否已被注册*/
                if (userService.queryUserByPhone(userParam.getPhone())==null){
                    /*4 调用远程服务  执行 注册*/
                   User user = userService.userRegister(userParam.getPhone(),userParam.getLoginPassword());
                   if (user!=null){
                       result = Result.SUCCESS();
                   }
                }else {
                    result.setCodeEnum(Code.PHONE_HAD_REGISTER);
                }
            }else {
                result.setCodeEnum(Code.SMS_CODE_INVALIDATE);
            }
        }else {
            result.setCodeEnum(Code.QUERY_PARAM_ERROR);
        }
        return result;
    }

    /*登录*/
    @PostMapping("/v1/user/accessToken")
    public Result accessToken(@RequestBody UserParam userParam){
        Result result = Result.FAILURE();
        /*1 检查数据  手机号码格式 密码长度（md5加密之后长度为 32）*/
        if (CommonUtil.checkPhone(userParam.getPhone())&&
                userParam.getCode()!=null&&userParam.getCode().length()==6
                &&userParam.getLoginPassword()!=null&&userParam.getLoginPassword().length()==32
        ) {
            /*2检查验证码 是否 正确*/
            if (smsService.checkLoginCode(userParam.getPhone(),userParam.getCode())){
               /*3 登录验证  用户是否存在*/
               User user = userService.userLogin(userParam.getPhone(),userParam.getLoginPassword());
               if (user!=null){
                   /*登录通过*/
                   Map<String,Object> payLoad = new HashMap<>();
                   payLoad.put("uid",user.getId());
                   payLoad.put("name",user.getName());
                   /*创建 token*/
                   String jwt = tokenUtil.createJwt(payLoad, 120);
                   result = Result.SUCCESS();
                   result.setAccessToken(jwt);
                   /*存入 前端: 用于前端页面*/
                   Map<String,Object> userView = new HashMap<>();
                   userView.put("uid",user.getId());
                   userView.put("name",user.getName());
                   userView.put("phone",user.getPhone());
                   result.setObject(userView);
                   /*在redis中 储存 token  以 token作为key 以 user 作为 value*/
                   stringRedisTemplate
                           .boundValueOps(RedisKey.YLB_LOGIN_TOKEN+jwt)
                           .set(JSONObject.toJSONString(user),2, TimeUnit.HOURS);
               }else {
                   /*登录失败*/
                   result.setCodeEnum(Code.LOGIN_ERROR);
               }
            }else {
                result.setCodeEnum(Code.SMS_CODE_INVALIDATE);
            }
        }else {
            result.setCodeEnum(Code.QUERY_PARAM_ERROR);
        }
        return result;
    }

    /*用户的详情信息     测试 登录*/
    @GetMapping("/v1/user/info")
    public Result userInfo(HttpServletRequest request){
        Result result = Result.SUCCESS();
        /*省略  获取 用户信息，可用资金，投资记录 充值记录  收益记录  共 5 表*/
        /*通过uid 从数据空中湖区*/
        Integer uid = Integer.parseInt((String) request.getAttribute("uid")) ;
        User user = userService.queryUserById(uid);
        /*获取用户的 账号 钱*/
        FinanceAccount financeAccount = financeService.queryByUid(uid);
        UserInfo userInfo = new UserInfo();
        userInfo.setName(user.getName());
        userInfo.setAccountMoney(financeAccount.getAvailableMoney());
        result.setObject(userInfo);
        return result;
    }


    /*退出登录   把redis中 对应的 token数据 清除  */
    @GetMapping("/v1/user/logout")
    public Result logout(HttpServletRequest request){
        Result result = Result.SUCCESS();
        /*把redis中 对应的 token数据 清除*/
        String authorization = request.getHeader("Authorization");
        String token = authorization.replaceAll("Bearer ", "");
        stringRedisTemplate.delete(RedisKey.YLB_LOGIN_TOKEN+token);
        /*添加 没有token时 用户也退出的 各种判断*/
        /*给前端的 token  重新赋值 为 “”*/
        return result;
    }
}
